package com.wjtc.common.utils.validate.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import com.wjtc.common.utils.validate.annotation.Email;
import com.wjtc.common.utils.validate.annotation.IsNumber;
import com.wjtc.common.utils.validate.annotation.Length;
import com.wjtc.common.utils.validate.annotation.Methods;
import com.wjtc.common.utils.validate.annotation.NotNull;
import com.wjtc.common.utils.validate.entity.ErrorMsg;


public class ValidateUtil {

	public static String validateSingleError(Object obj) {
		String error = null;
		Field[] fields = getAllFields(obj);
		for (Field f : fields) {
			try {
				Object value = getFieldValue(f, obj);
				Annotation[] as = f.getAnnotations();
				for (Annotation a : as) {
					error = validateField(a, value,obj);
					if (error != null && !"".equals(error.trim())) {
						return error;
					}
					break;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return error;
	}

	public static ErrorMsg validate(Object obj) {
		ErrorMsg errors = new ErrorMsg();
		Field[] fields = getAllFields(obj);
		for (Field f : fields) {
			String error = null;
			try {
				String name = f.getName();

				Object value = getFieldValue(f, obj);
				Annotation[] as = f.getAnnotations();
				for (Annotation a : as) {
					error = validateField(a, value,obj);
					if (error != null && !"".equals(error.trim())) {
						errors.getErrors().put(name, error);
					}
					break;
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return errors;
	}

	/**
	 *
	 * @Method: com.boozhong.common.validate.util.ValidateUtil.getAllFields
	 * @Description: 获取实体类中的 fields
	 * @author: WenBin
	 * @date: 2016年8月2日
	 * @version: 1.0
	 * @param obj
	 * @return
	 * Field[]
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	private static Field[] getAllFields(Object obj) {
		return obj.getClass().getDeclaredFields();
	}

	/**
	 *
	 * @Method: com.boozhong.common.validate.util.ValidateUtil.getFieldValue
	 * @Description:  校验 field 上的注解
	 * @author: WenBin
	 * @date: 2016年8月2日
	 * @version: 1.0
	 * @param f
	 * @param obj
	 * @return
	 * @throws Exception
	 * Object
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	private static Object getFieldValue(Field f, Object obj) throws Exception {
		String name = f.getName();
		name = name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
		Method m = obj.getClass().getMethod("get" + name);
		return m.invoke(obj);
	}

	/**
	 *
	 * @Method: com.boozhong.common.validate.util.ValidateUtil.length
	 * @Description:  注解 length 判断字符串的长度
	 * @author: WenBin
	 * @date: 2016年8月2日
	 * @version: 1.0
	 * @param value
	 * @return
	 * int
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	private static int length(String value) {
		int valueLength = 0;
		String chinese = "[\u0391-\uFFE5]";
		for (int i = 0; i < value.length(); i++) {
			String temp = value.substring(i, i + 1);
			if (temp.matches(chinese)) {
				valueLength += 2;
			} else {
				valueLength += 1;
			}
		}
		return valueLength;
	}

	/**
	 *
	 * @Method: com.boozhong.common.validate.util.ValidateUtil.validateField
	 * @Description: 校验字段是否合法
	 * @author: WenBin
	 * @date: 2016年8月2日
	 * @version: 1.0
	 * @param a
	 * @param value
	 * @param obj
	 * @return
	 * @throws Exception
	 * String
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	private static String validateField(Annotation a, Object value,Object obj) throws Exception {
		String error = "";
		// NOTNULL
		if (a instanceof NotNull) {
			NotNull aon = (NotNull) a;
			if (value == null) {
				error = aon.msg();
			} else {
				if (value instanceof String) {
					if ("".equals(((String) value).trim())) {
						error = aon.msg();
					}
				}
			}
			// IsNumber
		} else if (a instanceof IsNumber) {
			IsNumber aon = (IsNumber) a;
			if (value == null) {
				error = aon.msg();
			}
			if (value instanceof String) {
				String str = ((String) value).trim();
				String reg1 = "^-?\\d+$";
				String reg2 = "^(-?\\d+)(\\.\\d+)?$";
				if (!str.matches(reg1) && !str.matches(reg2)) {
					error = aon.msg();
				}
			}
			// email
		} else if (a instanceof Email) {
			Email aon = (Email) a;
			if (value == null) {
				error = aon.msg();
			}
			String mail = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
			String str = ((String) value).trim();
			if (!str.matches(mail)) {
				error = aon.msg();
			}
		} else if (a instanceof Length) {
			Length aon = (Length) a;
			if (value == null) {
				error = aon.msg();
			}
			if (value instanceof String) {
				String str = (String)value ;
				int length = length(str);
				int max = aon.max();
				int min = aon.min();
				if(max < length || min >length){
					error = aon.msg();
				}
			}
			//method
		} else if (a instanceof com.wjtc.common.utils.validate.annotation.Method) {
			com.wjtc.common.utils.validate.annotation.Method aon = (com.wjtc.common.utils.validate.annotation.Method) a;
			String mName = aon.method();
			if(!"".equals(mName.trim())){
				Method m = obj.getClass().getMethod(mName);
				String err =(String)m.invoke(obj);
				if(err!=null && !"".equals(err.trim())){
					error = err;
				}
			}
		} else if(a instanceof Methods){
			Methods aon = (Methods)a;
			String mName = aon.methods();
			if(!"".equals(mName.trim())){
				String [] names = mName.split(",");
				String err = "" ;
				for(String methodName : names){
					Method m = obj.getClass().getMethod(methodName);
					err =(String) m.invoke(obj);
					if(!"".equals(err)){
						error = err;
						break;
					}
				}
			}
		}
		return error;
	}
}
